﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GenerateAdminPage.Classes.FrmClasses
{
    #region USING
    using GenerateAdminPage.Classes.Helpers;
    using GenerateAdminPage.Classes.DBStructure;
    #endregion

    public class FrmClassesComplex : AbstractFrmClass
    {
        public override string GenerateClass()
        {
            StringBuilder Result = new StringBuilder();

            Result.AppendLine(TAB + "public partial class FrmLap" + TblOne.Name + " : Office2007Form");
            Result.AppendLine(TAB + "{");
            Result.AppendLine(GenerateVariables());
            Result.AppendLine(GenerateConstructor());
            Result.AppendLine(GenerateFormLoad());
            Result.AppendLine(GenerateInitGridView());
            Result.AppendLine(GenerateInitHiddenFields());
            Result.AppendLine(GenerateInitDataSource());
            Result.AppendLine(GeneratebtnChonThamChieu_Click());
            Result.AppendLine(GeneratebtnThem_Click());
            Result.AppendLine(GeneratebtnXoa_Click());
            Result.AppendLine(GenerateValidateInput());
            Result.AppendLine(GeneratebtnCapNhat_Click());
            Result.AppendLine(GeneratebtnThoat_Click());
            Result.AppendLine(GenerateActionUpdate());
            Result.AppendLine(GenerateLoadDataTable());
            Result.AppendLine(GenerateLoadManyData());
            Result.AppendLine(TAB + "}");

            return Result.ToString();
        }

        public string GenerateFormLoad()
        {
            StringBuilder Result = new StringBuilder();

            Result.AppendLine(TAB2 + "private void FrmLap" + TblOne.Name + "_Load(object sender, EventArgs e)");
            Result.AppendLine(TAB2 + "{");
            Result.AppendLine(TAB3 + "InitGridView();");
            Result.AppendLine(TAB3 + "InitHiddenFields();");
            Result.AppendLine(TAB3 + "InitDataSource();");
            Result.AppendLine(TAB3 + "if (" + Utils.GetPK(TblOne).Name + " != -1)");
            Result.AppendLine(TAB3 + "{");
            Result.AppendLine(TAB4 + "Load" + TblOne.Name + "();");
            Result.AppendLine(TAB3 + "}");
            Result.AppendLine(TAB2 + "}");

            return Result.ToString();
        }

        public string GenerateLoadDataTable()
        {
            StringBuilder Result = new StringBuilder();

            Result.AppendLine(TAB2 + "private void Load" + TblOne.Name + "()");
            Result.AppendLine(TAB2 + "{");
            Result.AppendLine(TAB3 + "var " + TblOne.Name.ToLower() + " = " + TblOne.Name + "Repository.SelectByID(" + Utils.GetPK(TblOne).Name + ");");
            Result.AppendLine(TAB3 + "if (" + TblOne.Name.ToLower() + " != null)");
            Result.AppendLine(TAB3 + "{");

            foreach (var item in TblOne.Attributes)
            {
                if (item.IsPrimaryKey)
                {
                    Result.AppendLine(TAB4 + "txt" + item.Name + ".Text = " + item.Name + ".ToString();");
                }
                else if (item.IsForeignKey)
                {
                    if (!GlobalVariables.g_sTableNguoiDung.Contains(item.ReferTo))
                    {
                        Result.AppendLine(TAB4 + "txt" + item.Name + ".Text = " + TblOne.Name.ToLower() + "." + item.Name + ".ToString();");
                        var nameAttr = Utils.GetStrAttributeStartWithTen(Utils.GetTableByName(DB, item.ReferTo));
                        if (nameAttr == string.Empty)
                        {
                            Result.AppendLine(TAB4 + "txt" + item.ReferTo + ".Text = " + TblOne.Name.ToLower() + "." + item.ReferTo + "." + Utils.GetPK(Utils.GetTableByName(DB, item.ReferTo)).Name + ".ToString();");
                        }
                        else
                        {
                            Result.AppendLine(TAB4 + "txt" + item.ReferTo + ".Text = " + TblOne.Name.ToLower() + "." + item.ReferTo + "." + nameAttr + ";");
                        }
                    }
                }
                else
                {
                    if (item.Type == DataType.DATETIME)
                    {
                        Result.AppendLine(TAB4 + "dt" + item.Name + ".Value = " + TblOne.Name.ToLower() + "." + item.Name + ".Value;");
                    }
                    else if (item.Type == DataType.BOOL)
                    {
                        Result.AppendLine(TAB4 + "cbx" + item.Name + ".SelectedIndex = -1");
                    }
                    else
                    {
                        Result.AppendLine(TAB4 + "txt" + item.Name + ".Text = " + TblOne.Name.ToLower() + "." + item.Name + ".ToString();");
                    }
                }
            }

            Result.AppendLine(TAB4 + "Load" + TblMany.Name + "(" + TblOne.Name.ToLower() + ");");
            Result.AppendLine(TAB3 + "}");
            Result.AppendLine(TAB2 + "}");

            return Result.ToString();
        }

        public string GenerateLoadManyData()
        {
            StringBuilder Result = new StringBuilder();

            Result.AppendLine(TAB2 + "private void Load" + TblMany.Name + "(" + TblOne.Name + " " + TblOne.Name.ToLower() + ")");
            Result.AppendLine(TAB2 + "{");
            Result.AppendLine(TAB3 + "var lst = " + TblMany.Name + "Repository.SelectBy" + Utils.GetPK(TblOne).Name + "(" + TblOne.Name.ToLower() + "." + Utils.GetPK(TblOne).Name + ");");
            Result.AppendLine(TAB3 + "if (lst.Count > 0)");
            Result.AppendLine(TAB3 + "{");
            Result.AppendLine(TAB4 + "foreach (var item in lst)");
            Result.AppendLine(TAB4 + "{");
            Result.AppendLine(TAB5 + "DataSource.Rows.Add(" + BuildLoadManyData() + ");");
            Result.AppendLine(TAB4 + "}");
            Result.AppendLine(TAB3 + "}");
            Result.AppendLine(TAB2 + "}");

            return Result.ToString();
        }

        public string BuildLoadManyData()
        {
            StringBuilder Result = new StringBuilder();

            List<Attribute> lst = new List<Attribute>();

            for (int i = 0; i < TblMany.Attributes.Count; i++)
            {
                if (TblMany.Attributes[i].IsPrimaryKey ||
                    (TblMany.Attributes[i].IsForeignKey && TblMany.Attributes[i].Name == Utils.GetPK(TblOne).Name))
                {
                    continue;
                }

                if (TblMany.Attributes[i] != null)
                {
                    lst.Add(TblMany.Attributes[i]);
                }

                if (TblMany.Attributes[i].IsForeignKey)
                {
                    var att = Utils.GetAttributeStartWithTen(Utils.GetTableByName(DB, TblMany.Attributes[i].ReferTo));
                    if (att != null)
                    {
                        att.ReferTo = TblMany.Attributes[i].ReferTo;
                        lst.Add(att);
                    }
                }
            }

            Result.Append(Utils.BuildListColumnData3(lst));

            return Result.ToString();
        }

        public string GeneratebtnChonHinhAnh()
        {
            StringBuilder Result = new StringBuilder();

            for (int i = 0; i < TblOne.Attributes.Count; i++)
            {
                if (TblOne.Attributes[i].Type == DataType.IMAGE)
                {
                    Result.AppendLine(TAB2 + "private void btnChon" + TblOne.Attributes[i].Name + "_Click(object sender, EventArgs e)");
                    Result.AppendLine(TAB2 + "{");
                    Result.AppendLine(TAB3 + "if (openFileDialog1.ShowDialog() == DialogResult.OK)");
                    Result.AppendLine(TAB3 + "{");
                    Result.AppendLine(TAB4 + "ptb" + TblOne.Attributes[i].Name + ".Image = new Bitmap(openFileDialog1.FileName);");
                    Result.AppendLine(TAB3 + "}");
                    Result.AppendLine(TAB2 + "}" + END);

                    Result.AppendLine(TAB2 + "private void btnXoa" + TblOne.Attributes[i].Name + "_Click(object sender, EventArgs e)");
                    Result.AppendLine(TAB2 + "{");
                    Result.AppendLine(TAB3 + "ptb" + TblOne.Attributes[i].Name + ".Image = null;");
                    Result.AppendLine(TAB2 + "}" + END);
                }
            }

            return Result.ToString();
        }

        public string GeneratebtnChonThamChieu_Click()
        {
            StringBuilder Result = new StringBuilder();

            for (int i = 0; i < TblOne.Attributes.Count; i++)
            {
                if (TblOne.Attributes[i].IsForeignKey && !GlobalVariables.g_sTableNguoiDung.Contains(TblOne.Attributes[i].ReferTo))
                {
                    Result.AppendLine(TAB2 + "private void btnChon" + TblOne.Attributes[i].ReferTo + "_Click(object sender, EventArgs e)");
                    Result.AppendLine(TAB2 + "{");
                    Result.AppendLine(TAB3 + "FrmQuanLy" + TblOne.Attributes[i].ReferTo + " frm = new FrmQuanLy" + TblOne.Attributes[i].ReferTo + "(true);");
                    Result.AppendLine(TAB3 + "frm.Handler += Get" + TblOne.Attributes[i].ReferTo + ";");
                    Result.AppendLine(TAB3 + "frm.ShowDialog();");
                    Result.AppendLine(TAB2 + "}" + END);
                    Result.AppendLine(GenerateGetThamChieu(Utils.GetTableByName(DB, TblOne.Attributes[i].ReferTo)));
                }
            }

            return Result.ToString();
        }

        public string GenerateGetThamChieu(Table _tbl)
        {
            StringBuilder Result = new StringBuilder();

            Result.AppendLine(TAB2 + "public void Get" + _tbl.Name + "(object sender, EventArgs e)");
            Result.AppendLine(TAB2 + "{");
            Result.AppendLine(TAB3 + "var eventType = (TransferSimpleDataEvent)e;");
            Result.AppendLine(TAB3 + "string[] comp = eventType.Data.Split(new char[] { '#' });");
            Result.AppendLine(TAB3 + "txt" + Utils.GetPK(_tbl).Name + ".Text = comp[0];");
            Result.AppendLine(TAB3 + "txt" + _tbl.Name + ".Text = comp[1];");
            Result.AppendLine(TAB2 + "}");

            return Result.ToString();
        }

        public string GenerateVariables()
        {
            StringBuilder Result = new StringBuilder();

            if (Utils.HaveFKReferTo(DB, TblOne))
            {
                Result.AppendLine(TAB2 + "public EventHandler Handler { get; set; }");
                Result.AppendLine(TAB2 + "private DataTable DataSource;");
                Result.AppendLine(TAB2 + "private int " + Utils.GetPK(TblOne).Name + ";");
            }

            for (int i = 0; i < TblOne.Attributes.Count; i++)
            {
                if (TblOne.Attributes[i].IsForeignKey && !GlobalVariables.g_sTableNguoiDung.Contains(TblOne.Attributes[i].ReferTo))
                {
                    Result.AppendLine(TAB2 + "private DevComponents.DotNetBar.Controls.TextBoxX txt" + TblOne.Attributes[i].Name + ";");
                }
            }

            return Result.ToString();
        }

        public string GenerateInitDataSource()
        {
            StringBuilder Result = new StringBuilder();

            Result.AppendLine(TAB2 + "public void InitDataSource()");
            Result.AppendLine(TAB2 + "{");

            Result.AppendLine(TAB3 + "DataSource = new DataTable();");

            for (int i = 0; i < TblMany.Attributes.Count; i++)
            {
                if (TblMany.Attributes[i].IsPrimaryKey ||
                    (TblMany.Attributes[i].IsForeignKey && TblMany.Attributes[i].Name == Utils.GetPK(TblOne).Name))
                {
                    continue;
                }
                Result.AppendLine(TAB3 + "DataSource.Columns.Add(\"" + TblMany.Attributes[i].Name + "\");");
                if (TblMany.Attributes[i].IsForeignKey)
                {
                    Result.AppendLine(TAB3 + "DataSource.Columns.Add(\"" + Utils.GetStrAttributeStartWithTen(Utils.GetTableByName(DB, TblMany.Attributes[i].ReferTo)) + "\");");
                }
            }

            Result.AppendLine(TAB3 + "DataView objTimeSheetDV = new System.Data.DataView(DataSource);");
            Result.AppendLine(TAB3 + "objTimeSheetDV.AllowNew = false;");
            Result.AppendLine(TAB3 + "dtgvData.AutoGenerateColumns = false;");
            Result.AppendLine(TAB3 + "dtgvData.DataSource = objTimeSheetDV;");
            Result.AppendLine(TAB3 + "dtgvData.ClearSelection();");
            
            Result.AppendLine(TAB2 + "}");

            return Result.ToString();
        }

        public string GenerateInitHiddenFields()
        {
            StringBuilder Result = new StringBuilder();

            var found = false;

            for (int i = 0; i < TblOne.Attributes.Count; i++)
            {
                if (TblOne.Attributes[i].IsForeignKey)
                {
                    found = true;
                    break;
                }
            }

            if (!found)
            {
                return Result.ToString();
            }

            Result.AppendLine(TAB2 + "public void InitHiddenFields()");
            Result.AppendLine(TAB2 + "{");
            
            for (int i = 0; i < TblOne.Attributes.Count; i++)
            {
                if (TblOne.Attributes[i].IsForeignKey && !GlobalVariables.g_sTableNguoiDung.Contains(TblOne.Attributes[i].ReferTo))
                {
                    Result.AppendLine(TAB3 + "txt" + TblOne.Attributes[i].Name + " = new DevComponents.DotNetBar.Controls.TextBoxX");
                    Result.AppendLine(TAB3 + "{");
                    Result.AppendLine(TAB4 + "Name = \"txt" + TblOne.Attributes[i].Name + "\",");
                    Result.AppendLine(TAB4 + "Text = \"\"");
                    Result.AppendLine(TAB3 + "};");
                    Result.AppendLine(TAB3 + "txt" + TblOne.Attributes[i].Name + ".Visible = false;");
                }
            }

            Result.AppendLine(TAB2 + "}");

            return Result.ToString();
        }

        public string GenerateConstructor()
        {
            StringBuilder Result = new StringBuilder();

            Result.AppendLine(TAB2 + "public FrmLap" + TblOne.Name + "(" + BuildPKParam(TblOne) + ")");
            Result.AppendLine(TAB2 + "{");
            Result.AppendLine(TAB3 + "InitializeComponent();");
            Result.AppendLine(TAB3 + Utils.GetPK(TblOne).Name + " = " + Utils.GetPK(TblOne).Name.ToLower() + ";");
            Result.AppendLine(TAB2 + "}");

            return Result.ToString();
        }

        public string BuildPKParam(Table tbl)
        {
            StringBuilder Result = new StringBuilder();

            var PK = Utils.GetPK(tbl);
            switch (PK.Type)
            {
                case DataType.INT:
                    Result.Append("int " + PK.Name.ToLower() + " = -1");
                    break;
                case DataType.STRING:
                    Result.Append("string " + PK.Name.ToLower() + " = \"\"");
                    break;           
            }

            return Result.ToString();
        }

        public string GeneratebtnThem_Click()
        {
            StringBuilder Result = new StringBuilder();

            Result.AppendLine(TAB2 + "private void btnThem_Click(object sender, EventArgs e)");
            Result.AppendLine(TAB2 + "{");
            Result.AppendLine(TAB3 + "FrmCapNhat" + TblMany.Name + " frm = new FrmCapNhat" + TblMany.Name + "();");
            Result.AppendLine(TAB3 + "frm.Handler += Get" + TblMany.Name + ";");
            Result.AppendLine(TAB3 + "frm.ShowDialog();");
            Result.AppendLine(TAB2 + "}" + END);
            Result.AppendLine(GenerateAddManyToOne(Utils.GetTableByName(DB, TblMany.Name)));

            return Result.ToString();
        }

        public string GenerateAddManyToOne(Table _tblMany)
        {
            StringBuilder Result = new StringBuilder();

            Table tbl = GetTableRelationDetail();
            if (tbl != null)
            {
                Result.AppendLine(TAB2 + "public void Get" + _tblMany.Name + "(object sender, EventArgs e)");
                Result.AppendLine(TAB2 + "{");
                Result.AppendLine(TAB3 + "var eventType = (TransferSimpleDataEvent)e;");
                Result.AppendLine(TAB3 + "string[] comp = eventType.Data.Split(new char[] { '#' });");
                Result.AppendLine(TAB3 + "var item = " + tbl.Name + "Repository.SelectByID(int.Parse(comp[0]));");
                Result.AppendLine(TAB3 + "if(item != null)");
                Result.AppendLine(TAB3 + "{");
                Result.AppendLine(TAB4 + "DataSource.Rows.Add(" + BuildRelationDetailData() + ");");
                Result.AppendLine(TAB3 + "}");
                Result.AppendLine(TAB2 + "}");
            }

            return Result.ToString();
        }

        public string BuildRelationDetailData()
        {
            StringBuilder Result = new StringBuilder();
            List<Attribute> lst = new List<Attribute>();

            for (int i = 0; i < TblMany.Attributes.Count; i++)
            {
                if (TblMany.Attributes[i].IsPrimaryKey ||
                    (TblMany.Attributes[i].IsForeignKey && TblMany.Attributes[i].Name == Utils.GetPK(TblOne).Name))
                {
                    continue;
                }
                if (TblMany.Attributes[i].IsForeignKey)
                {
                    lst.Add(TblMany.Attributes[i]);
                    if (Utils.GetAttributeStartWithTen(Utils.GetTableByName(DB, TblMany.Attributes[i].ReferTo)) != null)
                    {
                        lst.Add(Utils.GetAttributeStartWithTen(Utils.GetTableByName(DB, TblMany.Attributes[i].ReferTo)));
                    }
                }
            }

            Result.Append(Utils.BuildListColumnData2(lst));
            Result.Append(", ");
            var count = 0;

            for (int i = 0; i < TblMany.Attributes.Count; i++)
            {
                if (!TblMany.Attributes[i].IsPrimaryKey && !TblMany.Attributes[i].IsForeignKey)
                {
                    count++;
                }
            }

            for (int i = 0; i < count; i++)
            {
                if (i < count - 1)
                {
                    Result.Append("comp[" + (i + 1) + "], ");
                }
                else
                {
                    Result.Append("comp[" + (i + 1) + "]");
                }
            }

            return Result.ToString();
        }

        public Table GetTableRelationDetail()
        {
            Table tbl = null; ;
            for (int i = 0; i < TblMany.Attributes.Count; i++)
            {
                if (TblMany.Attributes[i].IsForeignKey)
                {
                    if (TblMany.Attributes[i].Name != Utils.GetPK(TblOne).Name)
                    {
                        tbl = Utils.GetTableByName(DB, TblMany.Attributes[i].ReferTo);
                    }
                }
            }
            return tbl;
        }

        public string GeneratebtnXoa_Click()
        {
            StringBuilder Result = new StringBuilder();

            Result.AppendLine(TAB2 + "private void btnXoa_Click(object sender, EventArgs e)");
            Result.AppendLine(TAB2 + "{");
            Result.AppendLine(TAB3 + "if (DataSource.Rows.Count > 0)");
            Result.AppendLine(TAB3 + "{");
            Result.AppendLine(TAB4 + "DataSource.Rows.RemoveAt(dtgvData.SelectedRows[0].Index);");
            Result.AppendLine(TAB3 + "}");
            Result.AppendLine(TAB2 + "}");

            return Result.ToString();
        }

        public string GeneratebtnCapNhat_Click()
        {
            StringBuilder Result = new StringBuilder();

            Result.AppendLine(TAB2 + "private void btnCapNhat_Click(object sender, EventArgs e)");
            Result.AppendLine(TAB2 + "{");
            Result.AppendLine(TAB3 + "var errorText = \"\";");
            Result.AppendLine(TAB3 + "bool success = false;");
            Result.AppendLine(TAB3 + "if (!ValidateInput(ref errorText))");
            Result.AppendLine(TAB3 + "{");
            Result.AppendLine(TAB4 + "MessageBoxEx.Show(errorText, \"Lỗi\", MessageBoxButtons.OK, MessageBoxIcon.Error);");
            Result.AppendLine(TAB4 + "return;");
            Result.AppendLine(TAB3 + "}");
            Result.AppendLine(TAB3 + "if (ActionUpdate())");
            Result.AppendLine(TAB3 + "{");
            Result.AppendLine(TAB4 + "success = true;");
            Result.AppendLine(TAB3 + "}");
            Result.AppendLine(TAB3 + "if (success)");
            Result.AppendLine(TAB3 + "{");
            Result.AppendLine(TAB4 + "MessageBoxEx.Show(\"Cập nhật dữ liệu thành công\", \"Thông báo\", MessageBoxButtons.OK, MessageBoxIcon.Information);");
            Result.AppendLine(TAB3 + "}");
            Result.AppendLine(TAB3 + "else");
            Result.AppendLine(TAB3 + "{");
            Result.AppendLine(TAB4 + "MessageBoxEx.Show(\"Cập nhật dữ liệu thất bại\", \"Lỗi\", MessageBoxButtons.OK, MessageBoxIcon.Error);");
            Result.AppendLine(TAB3 + "}");
            Result.AppendLine(TAB2 + "}");

            return Result.ToString();
        }

        public string GeneratebtnThoat_Click()
        {
            StringBuilder Result = new StringBuilder();

            Result.AppendLine(TAB2 + "private void btnThoat_Click(object sender, EventArgs e)");
            Result.AppendLine(TAB2 + "{");
            Result.AppendLine(TAB3 + "this.Close();");
            Result.AppendLine(TAB2 + "}");

            return Result.ToString();
        }

        public string GeneratebtnReset_Click()
        {
            StringBuilder Result = new StringBuilder();

            Result.AppendLine(TAB2 + "private void btnReset_Click(object sender, EventArgs e)");
            Result.AppendLine(TAB2 + "{");
            for (int i = 0; i < TblOne.Attributes.Count; i++)
            {
                if (TblOne.Attributes[i].IsForeignKey)
                {
                    Result.AppendLine(TAB3 + "txt" + TblOne.Attributes[i].Name + ".Text = \"\";");
                    Result.AppendLine(TAB3 + "txt" + TblOne.Attributes[i].ReferTo + ".Text = \"\";");
                }
                else
                {
                    if (TblOne.Attributes[i].Type == DataType.DATETIME)
                    {
                        Result.AppendLine(TAB3 + "dt" + TblOne.Attributes[i].Name + ".Value = DateTime.MinValue;");
                    }
                    else if (TblOne.Attributes[i].Type == DataType.BOOL)
                    {
                        Result.AppendLine(TAB3 + "cbx" + TblOne.Attributes[i].Name + ".SelectedIndex = -1;");
                    }
                    else if (TblOne.Attributes[i].Type == DataType.IMAGE)
                    {
                        Result.AppendLine(TAB3 + "ptb" + TblOne.Attributes[i].Name + ".Image = null;");
                    }
                    else
                    {
                        Result.AppendLine(TAB3 + "txt" + TblOne.Attributes[i].Name + ".Text = \"\";");
                    }
                }
            }
            Result.AppendLine(TAB2 + "}");

            return Result.ToString();
        }

        public string GeneratebtndtgvData_CellClick()
        {
            StringBuilder Result = new StringBuilder();

            Result.AppendLine(TAB2 + "private void dtgvData_CellClick(object sender, DataGridViewCellEventArgs e)");
            Result.AppendLine(TAB2 + "{");
            Result.AppendLine(TAB3 + "if (dtgvData.SelectedRows == null || dtgvData.SelectedRows.Count == 0)");
            Result.AppendLine(TAB4 + "return;");
            Result.AppendLine(TAB3 + "var selectedItem = dtgvData.SelectedRows[0];");
            Result.AppendLine(TAB3 + "txt" + Utils.GetPK(TblOne).Name + ".Text = dtgvData.SelectedRows[0].Cells[\"" + Utils.GetPK(TblOne).Name + "\"].Value.ToString();");
            Result.AppendLine(TAB3 + "var item = " + TblOne.Name + "Repository.SelectByID(" + Utils.BuildCastingPK(TblOne) + ");");
            Result.AppendLine(TAB3 + "LoadDetailInfo(item);");
            Result.AppendLine(TAB2 + "}");

            return Result.ToString();
        }

        public string GenerateLoadDetailInfo()
        {
            StringBuilder Result = new StringBuilder();

            Result.AppendLine(TAB2 + "public void LoadDetailInfo(" + TblOne.Name + " item)");
            Result.AppendLine(TAB2 + "{");
            for (int i = 0; i < TblOne.Attributes.Count; i++)
            {
                if (!TblOne.Attributes[i].IsPrimaryKey)
                {
                    if (TblOne.Attributes[i].IsForeignKey)
                    {
                        Result.AppendLine(TAB3 + "txt" + TblOne.Attributes[i].Name + ".Text = item." + TblOne.Attributes[i].Name + " == null ? \"\" : item." + TblOne.Attributes[i].Name + ".ToString();");
                        Result.AppendLine(TAB3 + "txt" + TblOne.Attributes[i].ReferTo + ".Text = item." + TblOne.Attributes[i].ReferTo + " == null ? \"\" : item." + TblOne.Attributes[i].ReferTo + "." + Utils.GetStrAttributeStartWithTen(Utils.GetTableByName(DB, TblOne.Attributes[i].ReferTo)) + ".ToString();");
                    }
                    else
                    {
                        if (TblOne.Attributes[i].Type == DataType.DATETIME)
                        {
                            Result.AppendLine(TAB3 + "dt" + TblOne.Attributes[i].Name + ".Value = item." + TblOne.Attributes[i].Name + " == null ? DateTime.MinValue : item." + TblOne.Attributes[i].Name + ".Value;");
                        }
                        else if (TblOne.Attributes[i].Type == DataType.BOOL)
                        {
                            Result.AppendLine(TAB3 + "cbx" + TblOne.Attributes[i].Name + ".SelectedIndex = item." + TblOne.Attributes[i].Name + " == null ? -1 : (item." + TblOne.Attributes[i].Name + ".Value ? 0 : 1);");
                        }
                        else if (TblOne.Attributes[i].Type == DataType.IMAGE)
                        {
                            Result.AppendLine(TAB3 + "if (item." + TblOne.Attributes[i].Name + "!= null)");
                            Result.AppendLine(TAB3 + "{");
                            Result.AppendLine(TAB4 + "try");
                            Result.AppendLine(TAB4 + "{");
                            Result.AppendLine(TAB5 + "Image newImage;");
                            Result.AppendLine(TAB5 + "using (MemoryStream ms = new MemoryStream(item." + TblOne.Attributes[i].Name + ", 0, item." + TblOne.Attributes[i].Name + ".Length))");
                            Result.AppendLine(TAB5 + "{");
                            Result.AppendLine(TAB6 + "ms.Write(item." + TblOne.Attributes[i].Name + ", 0, item." + TblOne.Attributes[i].Name + ".Length);");
                            Result.AppendLine(TAB6 + "newImage = Image.FromStream(ms, true);");
                            Result.AppendLine(TAB5 + "}");
                            Result.AppendLine(TAB5 + "ptb" + TblOne.Attributes[i].Name + ".Image = newImage;");
                            Result.AppendLine(TAB4 + "}");
                            Result.AppendLine(TAB4 + "catch (Exception ex)");
                            Result.AppendLine(TAB4 + "{");
                            Result.AppendLine(TAB5 + "MessageBox.Show(ex.ToString());");
                            Result.AppendLine(TAB4 + "}");
                            Result.AppendLine(TAB3 + "}");
                        }
                        else
                        {
                            Result.AppendLine(TAB3 + "txt" + TblOne.Attributes[i].Name + ".Text = item." + TblOne.Attributes[i].Name + " == null ? \"\" : item." + TblOne.Attributes[i].Name + ".ToString();");
                        }
                    }
                }
            }
            Result.AppendLine(TAB2 + "}");

            return Result.ToString();
        }

        public string GenerateInitGridView()
        {
            StringBuilder Result = new StringBuilder();

            Result.AppendLine(TAB2 + "private void InitGridView()");
            Result.AppendLine(TAB2 + "{");

            var declared = false;
            var sForeignTblName = "";
            var addForeignName = false;
            int numAttr = 0;

            for (int i = 0; i < TblMany.Attributes.Count; i++)
            {
                // Init except priomary key and foreign key refer to _table
                if (TblMany.Attributes[i].IsPrimaryKey ||
                    (TblMany.Attributes[i].IsForeignKey && TblMany.Attributes[i].Name == Utils.GetPK(TblOne).Name))
                {
                    continue;
                }
                numAttr++;
            }

            for (int i = 0; i < TblMany.Attributes.Count; i++)
            {
                // Init except priomary key and foreign key refer to _table
                if (TblMany.Attributes[i].IsPrimaryKey ||
                    (TblMany.Attributes[i].IsForeignKey && TblMany.Attributes[i].Name == Utils.GetPK(TblOne).Name))
                {
                    continue;
                }

                if (declared)
                {
                    Result.AppendLine(TAB3 + "objColumn = new DataGridViewTextBoxColumn");
                }
                else
                {
                    Result.AppendLine(TAB3 + "DataGridViewTextBoxColumn objColumn = new DataGridViewTextBoxColumn");
                    declared = true;
                }

                Result.AppendLine(TAB3 + "{");
                Result.AppendLine(TAB4 + "HeaderText = \"" + TblMany.Attributes[i].Name + "\",");
                Result.AppendLine(TAB4 + "DataPropertyName = \"" + TblMany.Attributes[i].Name + "\",");
                Result.AppendLine(TAB4 + "Name = \"" + TblMany.Attributes[i].Name + "\",");

                if (i < TblMany.Attributes.Count - 1)
                {
                    Result.AppendLine(TAB4 + "Width = (int)((dtgvData.Width - dtgvData.RowHeadersWidth)*((double)1/" + (numAttr + 1) + "))");
                }
                else
                {
                    Result.AppendLine(TAB4 + "Width = (int)((dtgvData.Width - dtgvData.RowHeadersWidth)*((double)1/" + (numAttr + 1) + ")) - 1");
                }

                Result.AppendLine(TAB3 + "};");
                Result.AppendLine(TAB3 + "dtgvData.Columns.Add(objColumn);");

                if (TblMany.Attributes[i].IsForeignKey && !addForeignName)
                {
                    sForeignTblName = TblMany.Attributes[i].ReferTo;
                    // Create column name corresponding with foreign key
                    var foreignTbl = Utils.GetTableByName(DB, sForeignTblName);
                    if (foreignTbl != null)
                    {
                        Result.AppendLine(TAB3 + "objColumn = new DataGridViewTextBoxColumn");
                        Result.AppendLine(TAB3 + "{");
                        Result.AppendLine(TAB4 + "HeaderText = \"" + Utils.GetStrAttributeStartWithTen(foreignTbl) + "\",");
                        Result.AppendLine(TAB4 + "DataPropertyName = \"" + Utils.GetStrAttributeStartWithTen(foreignTbl) + "\",");
                        Result.AppendLine(TAB4 + "Width = (int)((dtgvData.Width - dtgvData.RowHeadersWidth)*((double)1/" + ((numAttr + 1)) + "))");
                        Result.AppendLine(TAB3 + "};");
                        Result.AppendLine(TAB3 + "dtgvData.Columns.Add(objColumn);");
                        addForeignName = true;
                    }
                }
            }

            Result.AppendLine(TAB2 + "}");

            return Result.ToString();
        }

        public string BuildListColumnData(List<Attribute> lst)
        {
            StringBuilder Result = new StringBuilder();

            for (int i = 0; i < lst.Count; i++)
            {
                if (i < lst.Count - 1)
                {
                    if (lst[i].Type == DataType.DATETIME)
                    {
                        Result.Append("String.Format(\"{0:dd/MM/yyyy}\", lstItem[i]." + lst[i].Name + "), ");
                    }
                    else if (lst[i].Type == DataType.BOOL)
                    {
                        Result.Append("lstItem[i]." + lst[i].Name + " == null ? \"\" : (lstItem[i]." + lst[i].Name + " == true ? \"Nam\" : \"Nữ\"), ");
                    }
                    else
                    {
                        Result.Append("lstItem[i]." + lst[i].Name + ", ");
                    }
                }
                else
                {
                    if (lst[i].Type == DataType.DATETIME)
                    {
                        Result.Append("String.Format(\"{0:dd/MM/yyyy}\", lstItem[i]." + lst[i].Name + ")");
                    }
                    else if (lst[i].Type == DataType.BOOL)
                    {
                        Result.Append("lstItem[i]." + lst[i].Name + " == null ? \"\" : (lstItem[i]." + lst[i].Name + " == true ? \"Nam\" : \"Nữ\")");
                    }
                    else
                    {
                        Result.Append("lstItem[i]." + lst[i].Name);
                    }
                }
            }

            return Result.ToString();
        }

        public string GenerateValidateInput()
        {
            StringBuilder Result = new StringBuilder();

            Result.AppendLine(TAB2 + "private bool ValidateInput(ref string errorText)");
            Result.AppendLine(TAB2 + "{");
            Result.AppendLine(TAB3 + "if (DataSource.Rows.Count == 0)");
            Result.AppendLine(TAB3 + "{");
            Result.AppendLine(TAB4 + "errorText = \"Danh sách hiện thời không có gì!\";");
            Result.AppendLine(TAB4 + "return false;");
            Result.AppendLine(TAB3 + "}");
            Result.AppendLine(TAB3 + "return true;");
            Result.AppendLine(TAB2 + "}");

            return Result.ToString();
        }

        public string GenerateActionUpdate()
        {
            StringBuilder Result = new StringBuilder();

            Result.AppendLine(TAB2 + "private bool ActionUpdate()");
            Result.AppendLine(TAB2 + "{");
            Result.AppendLine(TAB3 + "try");
            Result.AppendLine(TAB3 + "{");
            Result.AppendLine(TAB4 + "DataContext.Instance.Connection.Open();");
            Result.AppendLine(TAB4 + "using (var transaction = DataContext.Instance.Connection.BeginTransaction())");
            Result.AppendLine(TAB4 + "{");
            Result.AppendLine(TAB5 + "var " + TblOne.Name.ToLower() + " = new " + TblOne.Name);
            Result.AppendLine(TAB5 + "{");

            for (int i = 0; i < TblOne.Attributes.Count; i++)
            {
                if(TblOne.Attributes[i].IsForeignKey && GlobalVariables.g_sTableNguoiDung.Contains(TblOne.Attributes[i].ReferTo))
                {
                    var name = string.Empty;
                    foreach (var user in GlobalVariables.g_sTableNguoiDung)
                    {
                        name = Utils.GetPK(Utils.GetTableByName(DB, user)).Name;
                        if (name != string.Empty)
                        {
                            break;
                        }
                    }
                    Result.AppendLine(TAB6 + TblOne.Attributes[i].Name + " = GlobalVariables.g_CurrentUser." + name + ",");
                }
                else if(!TblOne.Attributes[i].IsPrimaryKey || (TblOne.Attributes[i].IsPrimaryKey && !TblOne.Attributes[i].IsIdentify))
                {
                    if (TblOne.Attributes[i].Type == DataType.STRING)
                    {
                        Result.AppendLine(TAB6 + TblOne.Attributes[i].Name + " = txt" + TblOne.Attributes[i].Name + ".Text,");
                    }
                    else
                    {
                        if (TblOne.Attributes[i].Type == DataType.DATETIME)
                        {
                            Result.AppendLine(TAB6 + TblOne.Attributes[i].Name + " = DateTime.Now,");
                        }
                        else
                        {
                            Result.AppendLine(TAB6 + TblOne.Attributes[i].Name + " = " + Utils.GetDataType(TblOne.Attributes[i].Type) + ".Parse(txt" + TblOne.Attributes[i].Name + ".Text),");
                        }
                    }
                }
            }

            Result.AppendLine(TAB5 + "};");
            Result.AppendLine(TAB5 + "if (" + TblOne.Name + "Repository.Insert(" + TblOne.Name.ToLower() + "))");
            Result.AppendLine(TAB5 + "{");
            Result.AppendLine(TAB6 + "for (int i = 0; i <= DataSource.Rows.Count - 1; i++)");
            Result.AppendLine(TAB6 + "{");
            Result.AppendLine(TAB7 + "var " + TblMany.Name.ToLower() + " = new " + TblMany.Name);
            Result.AppendLine(TAB7 + "{");

            for (int i = 0; i < TblMany.Attributes.Count; i++)
            {
                if (!TblMany.Attributes[i].IsPrimaryKey ||
                    (TblMany.Attributes[i].IsPrimaryKey && !TblMany.Attributes[i].IsIdentify))
                {
                    if (TblMany.Attributes[i].IsForeignKey && TblMany.Attributes[i].Name == Utils.GetPK(TblOne).Name)
                    {
                        Result.AppendLine(TAB8 + TblMany.Attributes[i].Name + " = " + TblOne.Name.ToLower() + "." + Utils.GetPK(TblOne).Name + ",");
                    }
                    else
                    {
                        if (TblMany.Attributes[i].Type == DataType.STRING)
                        {
                            Result.AppendLine(TAB8 + TblMany.Attributes[i].Name + " = DataSource.Rows[i][\"" + TblMany.Attributes[i].Name + "\"].ToString(),");
                        }
                        else
                        {
                            if (TblMany.Attributes[i].Type == DataType.DATETIME)
                            {
                                Result.AppendLine(TAB8 + TblMany.Attributes[i].Name + " = DateTime.Now,");
                            }
                            else
                            {
                                Result.AppendLine(TAB8 + TblMany.Attributes[i].Name + " = " + Utils.GetDataType(TblMany.Attributes[i].Type) + ".Parse(DataSource.Rows[i][\"" + TblMany.Attributes[i].Name + "\"].ToString()),");
                            }
                        }
                    }
                }
            }

            Result.AppendLine(TAB7 + "};");
            Result.AppendLine(TAB7 + "if (!" + TblMany.Name + "Repository.Insert(" + TblMany.Name.ToLower() + "))");
            Result.AppendLine(TAB7 + "{");
            Result.AppendLine(TAB8 + "DataContext.Instance.Connection.Close();");
            Result.AppendLine(TAB8 + "return false;");
            Result.AppendLine(TAB7 + "}");
            Result.AppendLine(TAB6 + "}");
            Result.AppendLine(TAB6 + "transaction.Commit();");
            Result.AppendLine(TAB5 + "}");
            Result.AppendLine(TAB5 + "else");
            Result.AppendLine(TAB5 + "{");
            Result.AppendLine(TAB6 + "DataContext.Instance.Connection.Close();");
            Result.AppendLine(TAB6 + "return false;");
            Result.AppendLine(TAB5 + "}");
            Result.AppendLine(TAB4 + "}");
            Result.AppendLine(TAB4 + "DataContext.Instance.Connection.Close();");
            Result.AppendLine(TAB4 + "return true;");
            Result.AppendLine(TAB3 + "}");
            Result.AppendLine(TAB3 + "catch");
            Result.AppendLine(TAB3 + "{");
            Result.AppendLine(TAB4 + "DataContext.Instance.Connection.Close();");
            Result.AppendLine(TAB4 + "return false;");
            Result.AppendLine(TAB3 + "}");
            Result.AppendLine(TAB2 + "}");

            return Result.ToString();
        }

        public string GenerateActionDelete()
        {
            StringBuilder Result = new StringBuilder();

            Result.AppendLine(TAB2 + "private bool ActionDelete()");
            Result.AppendLine(TAB2 + "{");
            Result.AppendLine(TAB3 + "try");
            Result.AppendLine(TAB3 + "{");
            Result.AppendLine(TAB4 + "return " + TblOne.Name + "Repository.Delete(int.Parse(txt" + Utils.GetPK(TblOne).Name + ".Text));");
            Result.AppendLine(TAB3 + "}");
            Result.AppendLine(TAB3 + "catch");
            Result.AppendLine(TAB3 + "{");
            Result.AppendLine(TAB4 + "return false;");
            Result.AppendLine(TAB3 + "}");
            Result.AppendLine(TAB2 + "}");

            return Result.ToString();
        }
    }
}
